package com.ciquan.server.controller;

import com.ciquan.server.bean.BusinessStatus;
import com.ciquan.server.service.BusinessStatusService;
import com.ciquan.server.util.DateUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import java.util.*;

/**
 * Created by kakalee on 16/3/5.
 */
@Controller
@RequestMapping("")
public class BusinessController extends AbstractController {

    @Resource
    private BusinessStatusService businessStatusService;

    @RequestMapping("/businessDay/list")
    private ModelAndView day(ModelMap modelMap) {
        List<BusinessStatus> businessStatuses = businessStatusService.selectList(null);
        Map<Long, BusinessStatus> map = new LinkedHashMap<Long, BusinessStatus>();
        List<BusinessStatus> businessStatuses1 = new ArrayList<BusinessStatus>();
        List<BusinessStatus> businessStatuses2 = new ArrayList<BusinessStatus>();
        for(BusinessStatus businessStatus : businessStatuses) {
            add(map, businessStatus.getDate().getTime(), businessStatus);
            if(businessStatus.getType() == 0) {
                businessStatuses1.add(businessStatus);
            }

            else if(businessStatus.getType() == 1) {
                businessStatuses2.add(businessStatus);
            }
        }
        modelMap.put("businessStatuses1", businessStatuses1);
        modelMap.put("businessStatuses2", businessStatuses2);
        modelMap.put("businessStatuses3", map.values());

        return new ModelAndView("businessDay", modelMap);
    }

    @RequestMapping("/businessWeek/list")
    private ModelAndView week(ModelMap modelMap) {
        List<BusinessStatus> businessStatuses = businessStatusService.selectList(null);
        Map<Long, BusinessStatus> map = new LinkedHashMap<Long, BusinessStatus>();
        Map<Long, BusinessStatus> map1 = new LinkedHashMap<Long, BusinessStatus>();
        Map<Long, BusinessStatus> map2 = new LinkedHashMap<Long, BusinessStatus>();
        for(BusinessStatus businessStatus : businessStatuses) {
            businessStatus.setDate(DateUtils.getLastDayOfWeek(businessStatus.getDate()));
            if(businessStatus.getType() == 0) {
                add(map1, businessStatus.getDate().getTime(), businessStatus);
            }

            else {
                add(map2, businessStatus.getDate().getTime(), businessStatus);
            }
        }

        for(BusinessStatus businessStatus : map1.values()) {
            businessStatus.setType(0);
            add(map, businessStatus.getDate().getTime(), businessStatus);
        }

        for(BusinessStatus businessStatus : map2.values()) {
            businessStatus.setType(1);
            add(map, businessStatus.getDate().getTime(), businessStatus);
        }

        modelMap.put("businessStatuses1", map1.values());
        modelMap.put("businessStatuses2", map2.values());
        modelMap.put("businessStatuses3", map.values());

        return new ModelAndView("businessWeek", modelMap);
    }

    @RequestMapping("/businessMonth/list")
    private ModelAndView month(ModelMap modelMap) {
        List<BusinessStatus> businessStatuses = businessStatusService.selectList(null);
        Map<Long, BusinessStatus> map = new LinkedHashMap<Long, BusinessStatus>();
        Map<Long, BusinessStatus> map1 = new LinkedHashMap<Long, BusinessStatus>();
        Map<Long, BusinessStatus> map2 = new LinkedHashMap<Long, BusinessStatus>();
        for(BusinessStatus businessStatus : businessStatuses) {
            businessStatus.setDate(DateUtils.getFirstDayOfMonth(businessStatus.getDate()));
            if(businessStatus.getType() == 0) {
                add(map1, businessStatus.getDate().getTime(), businessStatus);
            }

            else {
                add(map2, businessStatus.getDate().getTime(), businessStatus);
            }
        }

        for(BusinessStatus businessStatus : map1.values()) {
            businessStatus.setType(0);
            add(map, businessStatus.getDate().getTime(), businessStatus);
        }

        for(BusinessStatus businessStatus : map2.values()) {
            businessStatus.setType(1);
            add(map, businessStatus.getDate().getTime(), businessStatus);
        }

        modelMap.put("businessStatuses1", map1.values());
        modelMap.put("businessStatuses2", map2.values());
        modelMap.put("businessStatuses3", map.values());

        return new ModelAndView("businessMonth", modelMap);
    }

    @RequestMapping("/businessYear/list")
    private ModelAndView year(ModelMap modelMap) {
        List<BusinessStatus> businessStatuses = businessStatusService.selectList(null);
        Map<Long, BusinessStatus> map = new LinkedHashMap<Long, BusinessStatus>();
        Map<Long, BusinessStatus> map1 = new LinkedHashMap<Long, BusinessStatus>();
        Map<Long, BusinessStatus> map2 = new LinkedHashMap<Long, BusinessStatus>();
        for(BusinessStatus businessStatus : businessStatuses) {
            businessStatus.setDate(DateUtils.getFirstDayOfYear(businessStatus.getDate()));
            if(businessStatus.getType() == 0) {
                add(map1, businessStatus.getDate().getTime(), businessStatus);
            }

            else {
                add(map2, businessStatus.getDate().getTime(), businessStatus);
            }
        }

        for(BusinessStatus businessStatus : map1.values()) {
            businessStatus.setType(0);
            add(map, businessStatus.getDate().getTime(), businessStatus);
        }

        for(BusinessStatus businessStatus : map2.values()) {
            businessStatus.setType(1);
            add(map, businessStatus.getDate().getTime(), businessStatus);
        }

        modelMap.put("businessStatuses1", map1.values());
        modelMap.put("businessStatuses2", map2.values());
        modelMap.put("businessStatuses3", map.values());

        return new ModelAndView("businessYear", modelMap);
    }

    @RequestMapping("/businessCompare/list")
    private ModelAndView compare(@RequestParam(value = "date1", required = false)String date1,
                                 @RequestParam(value = "date2", required = false)String date2,
                                 ModelMap modelMap) {

        if(StringUtils.isBlank(date1)) {
            date1 = DateUtils.formatToString(DateUtils.getFirstDayOfMonth(new Date()), DateUtils.yyyyMM);
        }

        if(StringUtils.isBlank(date2)) {
            date2 = DateUtils.formatToString(DateUtils.getFirstDayOfLastMonth(new Date()), DateUtils.yyyyMM);
        }

        Date d1 = DateUtils.parse(date1, DateUtils.yyyyMM);
        Date d2 = DateUtils.parse(date2, DateUtils.yyyyMM);

        Map<String, Object> params = new HashMap<String, Object>();
        params.put("startDate", DateUtils.formatToString(DateUtils.getFirstDayOfMonth(d1), DateUtils.yyyyMMdd));
        params.put("endDate", DateUtils.formatToString(DateUtils.getLastDayOfMonth(d1), DateUtils.yyyyMMdd));
        List<BusinessStatus> businessStatuses1 = businessStatusService.selectList(params);

        params.put("startDate", DateUtils.formatToString(DateUtils.getFirstDayOfMonth(d2), DateUtils.yyyyMMdd));
        params.put("endDate", DateUtils.formatToString(DateUtils.getLastDayOfMonth(d2), DateUtils.yyyyMMdd));
        List<BusinessStatus> businessStatuses2 = businessStatusService.selectList(params);

        Map<Long, BusinessStatus> map1 = new LinkedHashMap<Long, BusinessStatus>();
        Map<Long, BusinessStatus> map2 = new LinkedHashMap<Long, BusinessStatus>();
        for(BusinessStatus businessStatus : businessStatuses1) {
            add(map1, businessStatus.getDate().getTime(), businessStatus);
        }

        for(BusinessStatus businessStatus : businessStatuses2) {
            add(map2, businessStatus.getDate().getTime(), businessStatus);
        }

        modelMap.put("businessStatuses1", map1.values());
        modelMap.put("businessStatuses2", map2.values());
        modelMap.put("date1", date1);
        modelMap.put("date2", date2);

        return new ModelAndView("businessCompare", modelMap);
    }


    private void add(Map<Long, BusinessStatus> map, Long key, BusinessStatus businessStatus) {
        BusinessStatus businessStatus1 = map.get(key);
        if(businessStatus1 == null) {
            businessStatus1 =  new BusinessStatus();
            businessStatus1.setDate(businessStatus.getDate());
            businessStatus1.setTraffic(businessStatus.getTraffic());
            businessStatus1.setUserCount(businessStatus.getUserCount());
            businessStatus1.setOrderAmount(businessStatus.getOrderAmount());
            businessStatus1.setOrderUserCount(businessStatus.getOrderUserCount());
            businessStatus1.setOrderCount(businessStatus.getOrderCount());
            businessStatus1.setGoodsCount(businessStatus.getGoodsCount());
            map.put(businessStatus.getDate().getTime(), businessStatus1);
        }

        else {
            businessStatus1.setTraffic(businessStatus1.getTraffic() + businessStatus.getTraffic());
            businessStatus1.setUserCount(businessStatus1.getUserCount() + businessStatus.getUserCount());
            businessStatus1.setOrderAmount(businessStatus1.getOrderAmount() + businessStatus.getOrderAmount());
            businessStatus1.setOrderUserCount(businessStatus1.getOrderUserCount() + businessStatus.getOrderUserCount());
            businessStatus1.setOrderCount(businessStatus1.getOrderCount() + businessStatus.getOrderCount());
            businessStatus1.setGoodsCount(businessStatus1.getGoodsCount() + businessStatus.getGoodsCount());
            if(businessStatus1.getOrderAmount()> 0) {
                if(businessStatus.getType() == 0) {
                    float percent = (businessStatus1.getOrderAmount() - businessStatus.getOrderAmount()) * 100.0f / businessStatus1.getOrderAmount();
                    businessStatus1.setPercent(percent);
                }

                else {
                    float percent = businessStatus.getOrderAmount() * 100.0f / businessStatus1.getOrderAmount();
                    businessStatus1.setPercent(percent);
                }
            }
        }
    }
}
